#pragma once
#include "Texture.h"
#include "DX9Engine.h"
#include "Input.h"
#include "EngineData.h"
#include "Bullet.h"
#include "Physic\PhysicObject.h"
#include "Physic\PhysicSystem.h"

class Entity {
protected:
	Texture m_pTexture;
	float m_scale;
	float m_rotation;
	float m_speed;
	int m_durability;
	bool m_bMoving;
	bool m_bDead;

	LPCWSTR m_bulletFileName;

public:
	// Physic Object - made it public for easy access
	// I don't see the point in making accessor and mutators for it.
	// This should be passed into the Create function of the Physic System.
	// The Physic System does not own this Physic Object. It should be release 
	// when it's no longer used. 
	PhysicObject m_PhysicObject;

	PhysicSystem *m_PhysicSystem;

public:
	LinkedList<Bullet *> m_BulletList;
	Entity(){
		m_PhysicSystem = 0;
	};
	~Entity(){};

	virtual void initialize(LPCWSTR fileName, LPCWSTR a_bulletFileName, PhysicSystem *a_PhysicSystem) {
		m_PhysicSystem = a_PhysicSystem;
		m_pTexture.initialize(fileName);
		m_bulletFileName = a_bulletFileName;
	}
	virtual void setData(V2DF position, V2DF velocity, float scale, float rotation, float speed, int durability) {
		// Physic Object 
		// Setting the Physic Object
		m_PhysicObject.m_position.set(position.x, position.y);
		m_PhysicObject.m_velocity.set(velocity.x, velocity.y);

		m_scale = scale;
		m_rotation = rotation;
		m_speed = speed;
		m_durability = durability;
		m_bDead = false;
		m_bMoving = false;
	}
	virtual void update(){
		for(int i = 0; i < m_BulletList.Get_Size(); i++){
			m_BulletList.Get_Data(i)->Update();
			if(!onScreen(m_BulletList.Get_Data(i)->m_PhysicObject) ) {
				m_PhysicSystem->Destroy(&m_BulletList.Get_Data(i)->m_PhysicObject);
				m_BulletList.Get_Data(i)->Release();
				m_BulletList.Remove_FromIndex(i);
			}
		}
	};

	bool onScreen(PhysicObject p) {
		if(p.m_position.x > 0 - WINDOWBUFF && p.m_position.x < SCREEN_WIDTH + WINDOWBUFF && p.m_position.y > 0 - WINDOWBUFF && p.m_position.y < SCREEN_HEIGHT + WINDOWBUFF) {
			return true;
		}
		else {
			return false;
		}
	}

	virtual void render(){
		// Draw our Graphic Object, which is our texture, 
		// at the position our Physic Object is located at.
		// Think of the Physic Object as the physical part of 
		// our Entity. The texture is, well, the texture of
		// that Entity and it is where our Physic Object is located
		m_pTexture.draw(V2DF(m_PhysicObject.m_position.x, m_PhysicObject.m_position.y), m_rotation, m_scale, true);

		for(int i = 0; i < m_BulletList.Get_Size(); i++){
			if(m_BulletList.Get_Data(i)) {
				m_BulletList.Get_Data(i)->Draw();
			}
		}
	};
	virtual void release(){
		// Physic Object
		m_PhysicObject.Release();

		for(int i = 0; i < m_BulletList.Get_Size(); i++){
			m_PhysicSystem->Destroy(&m_BulletList.Get_Data(i)->m_PhysicObject);
			m_BulletList.Get_Data(i)->Release();
		}
		m_BulletList.Clear();
	};
	void setHP(int hp) { m_durability = hp; };
	int getHP(){ return m_durability;};
};